
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Xml.Linq;
using Microsoft.AspNetCore.Mvc;
using ST.Core;
using ST.Data;
using ST.ModelVM;
using ST.ModelVM.ProtocolDefine;
using ST.ModelVM.ProtocolSimHost;
using ST.Simulator.Tasks;


namespace ST.Simulator.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ProtocolSimHostController : ControllerBase
    {
        IRepository<Data.ProtocolDefine> __IRepositoryProtocolDefine;
        IRepository<Data.ProtocolSim> _IRepositoryProtocolSim;
        IRepository<Data.ProtocolSimHost> _IRepository ;

        List<ProtocolSimHostVM> lData;

       
        public ProtocolSimHostController(IRepository<Data.ProtocolDefine> repository1,
            IRepository<Data.ProtocolSim> repository2,
            IRepository<Data.ProtocolSimHost> repository3)
        {
            __IRepositoryProtocolDefine = repository1;
            _IRepositoryProtocolSim = repository2;
            _IRepository = repository3;

            lData = TransTask.Instance.lData;

        }   
        
        [HttpPost("Add")]
        public ProtocolSimHostAddVM Add(ProtocolSimHostAddVM mm){
            if (mm.HostId == 0)
            {
                throw new MyException("主机号必须输入");
            }
            var msim = _IRepositoryProtocolSim.GetById(mm.ProtocolSimId);
            var mdefine = __IRepositoryProtocolDefine.GetById(msim.ProtocolDefineId);

            var c = _IRepository.GetAll().Where(a => a.ProtocolSimId == msim.Id && a.HostId == mm.HostId).Count();
            if (c > 0)
            {
                throw new MyException("主机号重复");
            }
             

            var mhost=new ProtocolSimHost();
            mhost.Id= ST.Core.Util.IdUtil.NextId();
            mm.Id = mhost.Id;

            mhost.ProtocolSimId = mm.ProtocolSimId;
            mhost.HostId = mm.HostId;
            mhost.HostName = $"机号：{mhost.HostId}";
            mhost.Content = mdefine.Content;
            mhost.CrtDt = DateTime.Now;
            mhost.EdtDt = DateTime.Now;
            _IRepository.DB.Add(mhost);

            _IRepository.DB.SaveChanges();

            return mm;
        }


        [HttpPost("Edit")]
        public ProtocolSimHostAddVM Edit(ProtocolSimHostAddVM mm)
        {
          
           
            var m = _IRepository.GetById(mm.Id);
            if (mm.HostId == 0)
            {
                throw new MyException("主机号必须输入");
            }
            if (m.HostId != mm.HostId)
            {
                var c = _IRepository.GetAll().Where(a => a.ProtocolSimId == mm.ProtocolSimId && a.HostId == mm.HostId).Count();
                if (c > 0)
                {
                    throw new MyException("主机号重复");
                }
            }
            m.HostId = mm.HostId;
            m.HostName = $"机号：{m.HostId}";

            m.EdtDt = DateTime.Now;
             

            _IRepository.DB.SaveChanges();

            return mm;
        }

        [HttpPost("Delete")]
        public async Task<Data.ProtocolSimHost> Delete(Int64Model mm)
        {
            var m = _IRepository.GetById(mm.Id);
            _IRepository.DB.Remove(m);
             
            await _IRepository.DB.SaveChangesAsync();
            return m;
        }

        ProtocolSJZDVM FindSJZD(ProtocolSimHostVM m, string key)
        {
            for (var i = 0; i < m.SJZD.Count; i++)
            {
                if (m.SJZD[i].Name == key)
                {
                    return m.SJZD[i];
                }
            }
            return null;
        }

        [HttpPost("Detail")]
        public ProtocolSimHostVM Detail(Int64Model mm)
        {
            lock (lData)
            {
                var mdb = _IRepository.GetById(mm.Id);
                var m = lData.Where(a => a.Id == mm.Id).FirstOrDefault();
                if (m != null)
                {
                    m.HostId = mdb.HostId;
                    m.HostName=mdb.HostName;    
                    return m;
                }


                m = ST.Core.Util.JSON.DeserializeObject<ProtocolSimHostVM>(mdb.Content);
                m.Id = mdb.Id;
                m.ProtocolSimId=mdb.ProtocolSimId;
                m.HostId = mdb.HostId;
                m.HostName = mdb.HostName;


                for (var i = 0; i < m.GDSJ.Count; i++)
                {
                    if (m.GDSJ[i].PropValue == null)
                    {
                        m.GDSJ[i].PropValue = new List<PropValue>();
                    }
                    if (m.GDSJ[i].PropValue.Count == 0)
                    {
                        for (var j = 0; j < m.GDSJ[i].Data.Count; j++)
                        {
                            var o = m.GDSJ[i].Data[j];
                            var mPropValue = new PropValue { };
                            m.GDSJ[i].PropValue.Add(mPropValue);
                            switch (o.PropType)
                            {
                                case "值":
                                case "精度":
                                case "上限":
                                case "下限":

                                    mPropValue.NumValue = 0;
                                    mPropValue.StrValue = mPropValue.NumValue.ToString();
                                    break;
                                default:
                                    var sjzd = FindSJZD(m, o.SJZDKey);
                                    if (sjzd != null)
                                    {
                                        if (sjzd.Data.Count > 0)
                                        {
                                            mPropValue.NumValue = sjzd.Data[0].IMin.HasValue ? sjzd.Data[0].IMin.Value : sjzd.Data[0].IMax.Value;
                                            mPropValue.StrValue = sjzd.Data[0].Name;
                                        }
                                    }
                                    break;

                            }
                        }
                    }

                    m.GDSJ[i].CreateBytes();
                }


                for (var i = 0; i < m.XHSJ.Count; i++)
                {
                    if (m.XHSJ[i].PropValue == null)
                    {
                        m.XHSJ[i].PropValue = new List<List<PropValue>>();
                    }
                    if (m.XHSJ[i].PropValue.Count == 0)
                    {
                        for (var j = 0; j < 10; j++)
                        {
                            var row = new List<PropValue>();
                            m.XHSJ[i].PropValue.Add(row);

                            for (var k = 0; k < m.XHSJ[i].Data.Count; k++)
                            {
                                var o = m.XHSJ[i].Data[k];
                                var mPropValue = new PropValue { };
                                row.Add(mPropValue);
                                switch (o.PropType)
                                {
                                    case "值":
                                    case "精度":
                                    case "上限":
                                    case "下限":

                                        mPropValue.NumValue = 0;
                                        mPropValue.StrValue = mPropValue.NumValue.ToString();
                                        break;
                                    default:
                                        var sjzd = FindSJZD(m, o.SJZDKey);
                                        if (sjzd != null)
                                        {
                                            if (sjzd.Data.Count > 0)
                                            {
                                                mPropValue.NumValue = sjzd.Data[0].IMin.HasValue ? sjzd.Data[0].IMin.Value : sjzd.Data[0].IMax.Value;
                                                mPropValue.StrValue = sjzd.Data[0].Name;
                                            }
                                        }
                                        break;

                                }
                            }
                        }

                    }
                    m.XHSJ[i].CreateBytes();
                }

                lData.Add(m);
                return m;
            }
        }



         
       

        
        void SaveContent(ProtocolSimHostVM mm)
        {
            var Content = ST.Core.Util.JSON.SerializeObject(mm);
            var m=_IRepository.GetById(mm.Id);
            m.Content = Content;
            m.EdtDt = DateTime.Now;
            _IRepository.SaveChagnes();
        }
        
        
        [HttpPost("SaveGdData")]
        public ProtocolSimHostVM SaveGdData(ProtocolSimHostSaveValueVM mm)
        {
            ProtocolSimHostVM m;
            lock (lData)
            {
                m = lData.Where(a => a.Id == mm.Id).FirstOrDefault();
            }
            var gd1 = m.GDSJ[mm.I];
            var o = gd1.Data[mm.J];
            var mPropValue = gd1.PropValue[mm.J];
            switch (o.PropType)
            {
                case "值":
                case "精度":
                case "上限":
                case "下限":
                    mPropValue.StrValue = mm.StrValue;
                    mPropValue.NumValue = Convert.ToDecimal(mm.StrValue);
                    break;
                default:
                    var sjzd = FindSJZD(m, o.SJZDKey);
                    if (sjzd != null)
                    {
                        mPropValue.StrValue = mm.StrValue;
                        var msjzd=sjzd.Data.Where(a=>a.Name==mm.StrValue).FirstOrDefault();
                        if (msjzd != null)
                        {
                            mPropValue.NumValue = msjzd.IMin.HasValue ? msjzd.IMin.Value : msjzd.IMax.Value;
                        }
                         
                    }
                    break;
            }
            SaveContent(m);

            gd1.CreateBytes(); 

            return m;
        }

        [HttpPost("ImportGD")]
        public ProtocolSimHostVM ImportGD(ProtocolSimHostDRGDVM mm)
        {
            ProtocolSimHostVM m;
            lock (lData)
            {
                m = lData.Where(a => a.Id == mm.Id).FirstOrDefault();
            }
            var gd1 = m.GDSJ[mm.I];
            if (mm.StrValue.Count   != gd1.Data.Count)
            {
                throw new MyException("数据行数错误");
            }
            for(var j=0;j<mm.StrValue.Count;j++)
            {
                var o = gd1.Data[j]; 
                var mPropValue = gd1.PropValue[j];
                switch (o.PropType)
                {
                    case "值":
                    case "精度":
                    case "上限":
                    case "下限":
                        mPropValue.StrValue = mm.StrValue[j];
                        mPropValue.NumValue = Convert.ToDecimal(mm.StrValue[j]);
                        break;
                    default:
                        var sjzd = FindSJZD(m, o.SJZDKey);
                        if (sjzd != null)
                        {
                            mPropValue.StrValue = mm.StrValue[j];
                            var msjzd = sjzd.Data.Where(a => a.Name == mm.StrValue[j]).FirstOrDefault();
                            if (msjzd != null)
                            {
                                mPropValue.NumValue = msjzd.IMin.HasValue ? msjzd.IMin.Value : msjzd.IMax.Value;
                            }

                        }
                        break;
                }
            }
            SaveContent(m);
            gd1.CreateBytes();
            return m;
        }

        [HttpPost("ImportXH")]
        public ProtocolSimHostVM ImportXH(ProtocolSimHostDRXHVM mm)
        {
            ProtocolSimHostVM m;
            lock (lData)
            {
                m = lData.Where(a => a.Id == mm.Id).FirstOrDefault();
            }
            var gd1 = m.XHSJ[mm.I];
            gd1.PropValue.Clear();
            for (var ir = 0; ir < mm.StrValue.Count; ir++)
            {
                var rowPropValue=new List<PropValue>();
                var rowdata=mm.StrValue[ir];
                gd1.PropValue.Add(rowPropValue);
                for (var j = 0; j <gd1.Data.Count; j++)
                {
                    var o = gd1.Data[j];
                    var mPropValue = new PropValue();
                    rowPropValue.Add(mPropValue);
                    switch (o.PropType)
                    {
                        case "值":
                        case "精度":
                        case "上限":
                        case "下限":
                            mPropValue.StrValue = rowdata[j];
                            mPropValue.NumValue = Convert.ToDecimal(mPropValue.StrValue);
                            break;
                        default:
                            var sjzd = FindSJZD(m, o.SJZDKey);
                            if (sjzd != null)
                            {
                                mPropValue.StrValue = rowdata[j];
                                var msjzd = sjzd.Data.Where(a => a.Name == mPropValue.StrValue).FirstOrDefault();
                                if (msjzd != null)
                                {
                                    mPropValue.NumValue = msjzd.IMin.HasValue ? msjzd.IMin.Value : msjzd.IMax.Value;
                                }

                            }
                            break;
                    }
                }
            }
            
            SaveContent(m);
            gd1.CreateBytes();
            return m;
        }

        [HttpPost("SaveXhData")]
        public ProtocolSimHostVM SaveXhData(ProtocolSimHostSaveValueVM mm)
        {
            ProtocolSimHostVM m;
            lock (lData)
            {
                m = lData.Where(a => a.Id == mm.Id).FirstOrDefault();
            }
            var gd1 = m.XHSJ[mm.I];
            var row = gd1.PropValue[mm.J];

            var o = gd1.Data[mm.K];
            var mPropValue = row[mm.K];


            switch (o.PropType)
            {
                case "值":
                case "精度":
                case "上限":
                case "下限":
                    mPropValue.StrValue = mm.StrValue;
                    mPropValue.NumValue = Convert.ToDecimal(mm.StrValue);
                    break;
                default:
                    var sjzd = FindSJZD(m, o.SJZDKey);
                    if (sjzd != null)
                    {
                        mPropValue.StrValue = mm.StrValue;
                        var msjzd = sjzd.Data.Where(a => a.Name == mm.StrValue).FirstOrDefault();
                        if (msjzd != null)
                        {
                            mPropValue.NumValue = msjzd.IMin.HasValue ? msjzd.IMin.Value : msjzd.IMax.Value;
                        }

                    }
                    break;
            }
            SaveContent(m);
            gd1.CreateBytes();
            return m;
        }



     

    }
}